﻿using System.Linq;
using NUnit.Framework;
using StreetPacMan.Server.Facade;

namespace StreetPacMan.Server.Tests.Integ
{
    [TestFixture]
    public class BasicVisibility : BaseCleaner
    {
        [Test]
        public void DoServerPoll_AsPacMan_ShouldNotSeeGhostBeforeItPollsServer()
        {
            var instance = ServerFacadeFactory.GetServerFacade();

            instance.CreateGameX("GameName");
            var pacman = instance.JoinGameX("GameName", "PacManName", PlayerRole.PacMan);
            var ghost = instance.JoinGameX("GameName", "Ghost", PlayerRole.Ghost);

            var pollResult = instance.UpdateMyWhereabouts(new ServerPollParameters(pacman.PlayerId, 0, 0, true));

            var returnedPacmanEntity = pollResult.Players.Single();
            Assert.AreEqual(pacman.PlayerId, returnedPacmanEntity.EntityId);
        }

        [Test]
        public void DoServerPoll_AsPacMan_ShouldNotSeeGhostAfterItPollsServerDisabled()
        {
            var instance = ServerFacadeFactory.GetServerFacade();

            instance.CreateGameX("GameName");
            var pacman = instance.JoinGameX("GameName", "PacManName", PlayerRole.PacMan);
            var ghost = instance.JoinGameX("GameName", "Ghost", PlayerRole.Ghost);

            var ghostPollResult = instance.UpdateMyWhereabouts(new ServerPollParameters(ghost.PlayerId, 0, 0, false));
            var pacmanPollResult = instance.UpdateMyWhereabouts(new ServerPollParameters(pacman.PlayerId, 0, 0, true));

            CollectionAssert.IsEmpty(pacmanPollResult.Players.Where(x => x.Role == PlayerRole.Ghost));
        }
        [Test]
        public void DoServerPoll_AsPacMan_ShouldSeeGhostAfterItPollsServerEnabled()
        {
            var instance = ServerFacadeFactory.GetServerFacade();

            instance.CreateGameX("GameName");
            var pacman = instance.JoinGameX("GameName", "PacManName", PlayerRole.PacMan);
            var ghost = instance.JoinGameX("GameName", "Ghost", PlayerRole.Ghost);

            var ghostPollResult = instance.UpdateMyWhereabouts(new ServerPollParameters(ghost.PlayerId, 0, 0, true));
            var pacmanPollResult = instance.UpdateMyWhereabouts(new ServerPollParameters(pacman.PlayerId, 0, 0, true));

            Assert.AreEqual(ghost.PlayerId, pacmanPollResult.Players.Where(x => x.Role == PlayerRole.Ghost).Single().EntityId);
        }

        [Test]
        public void GetInitialGameState_AsGhost_ReturnEmptyApplesCollection()
        {
            var instance = ServerFacadeFactory.GetServerFacade();

            instance.CreateGameX("GameName");
            var ghost = instance.JoinGameX("GameName", "Ghost1", PlayerRole.Ghost);

            var initialGameState = instance.GetGameStateForX(ghost.PlayerId);

            CollectionAssert.IsEmpty(initialGameState.Apples);
        }

        [Test]
        public void GetInitialGameState_AsPacMan_ReturnAllApplesCollection()
        {
            var instance = ServerFacadeFactory.GetServerFacade();

            instance.CreateGameX("GameName");
            var pacMan = instance.JoinGameX("GameName", "PacManName", PlayerRole.PacMan);

            var initialGameState = instance.GetGameStateForX(pacMan.PlayerId);

            CollectionAssert.IsNotEmpty(initialGameState.Apples);
        }

        [Test]
        public void DoServerPoll_AsGhost_ShouldSeeItself()
        {
            var instance = ServerFacadeFactory.GetServerFacade();

            instance.CreateGameX("GameName");
            var ghost = instance.JoinGameX("GameName", "Ghost1", PlayerRole.Ghost);

            var pollResult = instance.UpdateMyWhereabouts(new ServerPollParameters(ghost.PlayerId, 0, 0, true));

            var returnedGhostEntity = pollResult.Players.Single();
            Assert.AreEqual(ghost.PlayerId, returnedGhostEntity.EntityId);
            Assert.AreEqual(PlayerRole.Ghost, returnedGhostEntity.Role);
        }


        [Test]
        public void DoServerPoll_AsGhost_WithPacManOutOfRange_ShouldSeeOnlyItself()
        {
            var instance = ServerFacadeFactory.GetServerFacade();

            instance.CreateGameX("GameName");
            var pacman = instance.JoinGameX("GameName", "PacManName", PlayerRole.PacMan);
            var ghost = instance.JoinGameX("GameName", "Ghost1", PlayerRole.Ghost);

            var pacmanPollResult = instance.UpdateMyWhereabouts(new ServerPollParameters(pacman.PlayerId, 10, 10, true));
            var ghostPollResult = instance.UpdateMyWhereabouts(new ServerPollParameters(ghost.PlayerId, 0, 0, true));

            var returnedGhostEntity = ghostPollResult.Players.Single();
            Assert.AreEqual(ghost.PlayerId, returnedGhostEntity.EntityId);
            Assert.AreEqual(PlayerRole.Ghost, returnedGhostEntity.Role);
  
        }

        [Test]
        public void DoServerPoll_AsGhost_WithPacManWithin30MeterRange_ShouldSeeitselfAndPacMan()
        {
            var instance = ServerFacadeFactory.GetServerFacade();

            instance.CreateGameX("GameName");
            var pacman = instance.JoinGameX("GameName", "PacManName", PlayerRole.PacMan);
            var ghost = instance.JoinGameX("GameName", "Ghost1", PlayerRole.Ghost);

            var pacmanPollResult = instance.UpdateMyWhereabouts(new ServerPollParameters(pacman.PlayerId, 32.06646, 34.7825, true));
            var ghostPollResult = instance.UpdateMyWhereabouts(new ServerPollParameters(ghost.PlayerId, 32.066697, 34.782275, true));

            var returnedGhostEntity = ghostPollResult.Players.Single(x => x.Role == PlayerRole.Ghost);
            var returnedPacManEntity = ghostPollResult.Players.Single(x => x.Role == PlayerRole.PacMan);

            Assert.AreEqual(ghost.PlayerId, returnedGhostEntity.EntityId);
            Assert.AreEqual(pacman.PlayerId, returnedPacManEntity.EntityId);
        }
    }
}